//
//  DataBaseManager.m
//  Demo
//
//  Created by chaichai on 2022/3/2.
//

#import "DataBaseManager.h"
#import "AppDelegate.h"
#import "NSDate+helper.h"
@implementation DataBaseManager

+(instancetype)sharedManager;
{
    static DataBaseManager *_M_ = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _M_ = [[DataBaseManager alloc] init];
    });
    return _M_;
}
- (NSManagedObjectContext *)contex
{
    AppDelegate *app = (id)UIApplication.sharedApplication.delegate;
    return app.persistentContainer.viewContext;
}
-(void)save
{
    AppDelegate *app = (id)UIApplication.sharedApplication.delegate;
    [app saveContext];
}

- (void)addRecord:(NSDate *)date
{
    [Group addRecord:date];
    [self save];
}

- (void)removeRecord:(NSDate *)date
{
    NSArray<Record *> *arr = [Record queryRecord:date];
    if (!arr || arr.count <= 0) {
        return;
    }
    
    Record *obj = arr.lastObject;
    if (arr.count == 1) {
        Group *gp = obj.group;
        if (gp.first == gp.last) {//连续打卡只有1天
            [gp removeRecordsObject:obj];
            [self.contex deleteObject:obj];
            [self.contex deleteObject:gp];
            [self save];
            return;
        }
        NSInteger day = date.day;
        if(gp.first == day){//移除连续打卡的第一天
            gp.first = day + 1;
            gp.count = MAX(0,gp.last - gp.first + 1);
        }else if (gp.last == day){//移除连续打卡的最后一天
            gp.last = day - 1;
            gp.count = MAX(0,gp.last - gp.first + 1);
        }else{//移除连续打卡中间日期的记录，需要拆分成2段连续打卡
            int64_t last = gp.last;
            NSArray *laterArray =
            [Record queryRecordBegin:day + 1 withEnd:last];
            gp.last = day - 1;
            gp.count = MAX(0,gp.last - gp.first + 1);
            [gp removeRecords:[NSSet setWithArray:laterArray]];
            
            Group *newGroup = [Group createGroup];
            newGroup.first = day + 1;
            newGroup.last = last;
            newGroup.count = MAX(0,newGroup.last - newGroup.first + 1);
            [newGroup addRecords:[NSSet setWithArray:laterArray]];
        }
        [gp removeRecordsObject:obj];
    }
    [self.contex deleteObject:obj];
    [self save];
}

- (NSInteger)totalRecords
{
    NSFetchRequest *request = [Record fetchRequest];
    request.resultType = NSCountResultType;
    NSError *error = nil;
    NSArray *dataList =
    [self.contex executeFetchRequest:request error:&error];
    NSInteger count = [dataList.firstObject integerValue];
    return count;
}

- (NSInteger)totalRecordDays
{
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    NSExpression *expression = [NSExpression expressionWithFormat:@"@sum.count"];
    expressionDescription.expression = expression;
    expressionDescription.expressionResultType = NSInteger64AttributeType;
    expressionDescription.name = @"total";
    
    NSFetchRequest *request = [Group fetchRequest];
    request.resultType = NSDictionaryResultType;
    request.propertiesToFetch = @[expressionDescription];
    NSError *errpr = nil;
    NSArray *array = [self.contex executeFetchRequest:request error:&errpr];
    if(!array || array.count <= 0){
        return 0;
    }
    NSDictionary *dict = [array lastObject];
    return [[dict objectForKey:@"total"] integerValue];
}

- (NSArray *)queryRecordsForDay:(NSDate *)date
{
    return [Record queryRecord:date];
}

- (NSInteger)ceaselessDaysWithDate:(NSDate *)date
{
    NSArray *arr = [Record queryRecord:date];
    if (!arr || arr.count <= 0) {
        return 0;
    }
    Record *obj = arr.lastObject;
    Group *gp = obj.group;
    return gp.count;
}

- (NSInteger)maximumCeaselessDays
{
    NSFetchRequest *request = [Group fetchRequest];
    NSSortDescriptor *sort =
    [NSSortDescriptor  sortDescriptorWithKey:@"count" ascending:NO];
    [request setSortDescriptors:@[sort]];
    request.fetchLimit = 1;
    
    NSError *error = nil;
    NSArray *resArr =
    [self.contex executeFetchRequest:request
                               error:&error];
    if (resArr && resArr.count > 0) {
        Group *gp = resArr.firstObject;
        return gp.count;
    }
    return 0;
}
@end
